package org.example.now.async.downloadexcel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.example.old.dto.CellDataReadDemoData;
import org.example.old.dto.SysDto;
import org.example.old.listener.DemoDataListener;
import org.example.old.listener.NoModelDataListener;
import org.example.old.service.SysService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/sys3")
public class ReadExecl {
    @Autowired
    SysService sysService;

    /**
     * 全量查询数据
     * @return
     */
    public List<SysDto> data() {
        return sysService.querList();
    }



    /**
     * 简单读取数据--easyexcel
     * 创建excel对应的实体
     * 由于默认一行行的读取excel，所以需要创建excel一行行的回调监听器
     * 直接读
     */
    @GetMapping("/queryList")
    public void queryList(){
        String filePath = "D:/demo.xlsx";
         // 写法1：JDK1.8，不用额外写一个监听器   11.15s 5万条数据
//        EasyExcel.read(filePath, SysDto.class,new PageReadListener<SysDto>(list->{
////            for (SysDto sysDto:list){
////                System.out.println("读取到一条数据：");
////            }
//            sysService.addUserList(list);
//
//        })).sheet().doRead();

        // 写法2：匿名内部类 不用额外写一个监听器   11.32s   5万条
//        EasyExcel.read(filePath, SysDto.class, new ReadListener<SysDto>() {
//            /**
//             * 单词缓存的数据量
//             */
//            public static final int BATCH_COUNT = 100;
//            /**
//             * 临时存储
//             */
//            private List<SysDto> list = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
//
//            @Override
//            public void invoke(SysDto sysDto, AnalysisContext analysisContext) {
//                list.add(sysDto);
//                if (list.size() >= BATCH_COUNT){
//                    saveData();
//                    list = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
//                }
//            }
//
//            @Override
//            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//                saveData();
//            }
//
//            private void saveData(){
//                sysService.addUserList(list);
//            }
//        }).sheet().doRead();

        // 写法3：DemoDataListener不能被spring管理，每次读取excel都要new，然后里面用sprinf可以构造方法传参  3.72s
        EasyExcel.read(filePath, SysDto.class,new DemoDataListener(sysService)).sheet().doRead();

        // 写法4：   3.67s
//        try(ExcelReader excelReader = EasyExcel.read(filePath, SysDto.class,new DemoDataListener(sysService)).build()){
//            // 构建一个sheet这里可以指定名字在或no
//            ReadSheet readSheet = EasyExcel.readSheet(0).build();
//            // 读取一个sheet
//            excelReader.read(readSheet);
//        }

        System.out.println("读取完成");

    }



    /**
     * 指定列的下标或者列名--easyexcel
     */
    @GetMapping("/queryList1")
    public void queryList1(){
        String filePath = "D:/demo.xlsx";

         EasyExcel.read(filePath, SysDto.class,new DemoDataListener(sysService)).sheet().doRead();
        System.out.println("读取完成");
    }

    /**
     * 读多个sheet--easyexcel
     */
    @GetMapping("/queryList2")
    public void queryList2(){
        String filePath = "D:/demo.xlsx";
        // 读取全部sheet
        // 这里需要注意 DemoDataListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个DemoDataListener里面写
         EasyExcel.read(filePath, SysDto.class,new DemoDataListener(sysService)).doReadAll();
         // 读取部分sheet

        // 写法1：
        try(ExcelReader excelReader = EasyExcel.read(filePath).build()){
            ReadSheet readSheet = EasyExcel.readSheet(0).head(SysDto.class)
                    .registerReadListener(new DemoDataListener(sysService)).build();
            ReadSheet readSheet2 = EasyExcel.readSheet(0).head(SysDto.class)
                    .registerReadListener(new DemoDataListener(sysService)).build();
            excelReader.read(readSheet,readSheet2);
        }
        System.out.println("读取完成");
    }

    /**
     * 日期、数字或者自定义格式转换--easyexcel
     */
    @GetMapping("/queryList3")
    public void queryList3(){
        String filePath = "D:/demo.xlsx";
        EasyExcel.read(filePath, SysDto.class,new DemoDataListener(sysService)).sheet().doRead();

        System.out.println("读取完成");
    }

    /**
     * 多行头--easyexcel
     */
    @GetMapping("/queryList4")
    public void queryList4(){
        String filePath = "D:/demo.xlsx";
        EasyExcel.read(filePath, SysDto.class,new DemoDataListener(sysService))
                // 从第三行开始取数
                .sheet().headRowNumber(2).doRead();
        System.out.println("读取完成");
    }

    /**
     * 同步的返回--easyexcel
     */
    @GetMapping("/queryList5")
    public void queryList5(){
        String filePath = "D:/demo.xlsx";
        List<SysDto> list =  EasyExcel.read(filePath).head(SysDto.class).sheet().doReadSync();
        for(SysDto dto :list){
            System.out.println("list:"+dto.toString());
        }
        List<Map<Integer,String>> map =  EasyExcel.read(filePath).sheet().doReadSync();
        for(Map<Integer,String> dto :map){
            System.out.println("map:"+dto.toString());
        }
        System.out.println("读取完成");
    }

    /**
     * 读取表头数据--easyexcel
     */
    @GetMapping("/queryList6")
    public void queryList6(){
        String filePath = "D:/demo.xlsx";
        EasyExcel.read(filePath, SysDto.class, new DemoDataListener(sysService)).sheet().doRead();
        System.out.println("读取完成");
    }


    /**
     * 额外信息（批注、超链接、合并单元格信息读取）--easyexcel
     */
    @GetMapping("/queryList7")
    public void queryList7(){
        String filePath = "D:/demo.xlsx";
        EasyExcel.read(filePath, SysDto.class, new DemoDataListener(sysService))
                // 需要读取批注，默认不读取
                .extraRead(CellExtraTypeEnum.COMMENT)
                // 需要读取超链接，默认不读取
                .extraRead(CellExtraTypeEnum.HYPERLINK)
                // 需要读取合并单元格信息，默认不读取
                .extraRead(CellExtraTypeEnum.MERGE)
                .sheet().doRead();
        System.out.println("读取完成");
    }


    /**
     * 读取公式和单元格类型--easyexcel
     */
    @GetMapping("/queryList8")
    public void queryList8(){
        String filePath = "D:/demo.xlsx";
        CellDataReadDemoData sysDto = new CellDataReadDemoData();
//        EasyExcel.read(filePath, new SysDto(sysDto).getClass(), new DemoDataListener(sysService)).sheet().doRead();
        System.out.println("读取完成");
    }

    /**
     * 数据转换等异常处理--easyexcel
     */
    @GetMapping("/queryList9")
    public void queryList9(){
        String filePath = "D:/demo.xlsx";
        CellDataReadDemoData sysDto = new CellDataReadDemoData();
//        EasyExcel.read(filePath, new SysDto(sysDto).getClass(), new DemoDataListener(sysService)).sheet().doRead();
        System.out.println("读取完成");
    }

    /**
     * 不创建对象的读--easyexcel
     */
    @GetMapping("/queryList10")
    public void queryList10(){
        String filePath = "D:/demo.xlsx";
        EasyExcel.read(filePath,  new DemoDataListener(sysService)).sheet().doRead();
        System.out.println("读取完成");
    }



}
